package hikari.instruments;

import com.gooddies.wiring.annotations.Wire;
import com.gooddies.wiring.annotations.WiringComponent;
import hikari.gui.panels.BasicObjectPropertiesPanel;
import hikari.gui.panels.ModifyPanel;
import hikari.managers.Manager3D;
import org.swig.jirr.ISceneCollisionManager;
import org.swig.jirr.ISceneNode;
import org.swig.jirr.IVideoDriver;
import org.swig.jirr.SMaterial;
import org.swig.jirr.vector2di;
import org.swig.jirr.vector3df;

/**
 * @author sad
 */
@WiringComponent(singleton = true, lazy = true)
public class MoveInstrument extends AbstractTransformationInstrument {
    @Wire
    private Manager3D manager3D;
    @Wire
    private ModifyPanel modifyPanel;
    protected vector3df node_state_before_changing = null;

    protected MoveInstrument() {
    }

    
    
    @Override
    protected void drawGizmo(ISceneNode node) {
        IVideoDriver driver = manager3D.getVideoDriver();
        node.updateAbsolutePosition();
        gizmo_position = node.getAbsolutePosition();
        drawMoveArrays(driver, gizmo_position);
    }

    protected void drawMoveArrays(IVideoDriver driver, vector3df position) {
        driver.setMaterial(xColor);
        driver.resetTransformMatrix();

        float axisSizes = getGizmoLength(position);
        drawArrow(position, position.addOperator(new vector3df(axisSizes, 0, 0)), selectedAxis == 'x' ? selectedColor : xColor, driver);
        drawArrow(position, position.addOperator(new vector3df(0, axisSizes, 0)), selectedAxis == 'y' ? selectedColor : yColor, driver);
        drawArrow(position, position.addOperator(new vector3df(0, 0, axisSizes)), selectedAxis == 'z' ? selectedColor : zColor, driver);
    }

    protected void drawArrow(vector3df start, vector3df end, SMaterial material, IVideoDriver driver) {
        driver.setMaterial(material);
        driver.draw3DLine(start, end);
    }

    @Override
    protected void changeObject(ISceneNode node, char axis, float length) {
        vector3df temp_position = new vector3df(node_state_before_changing);
        switch (axis) {
            case 'x':
                temp_position.addX(length);
                break;
            case 'y':
                temp_position.addY(length);
                break;
            case 'z':
                temp_position.addZ(length);
                break;
        }

        node.setPosition(temp_position);
        temp_position = node.getPosition();
        if (temp_position.getZ() == Float.NaN) {
            int x = 5;
            x++;
        }
        modifyPanel.updateTransformationData(BasicObjectPropertiesPanel.UPDATE_TYPE.MOVE);
        manager3D.render();
    }

    @Override
    protected float proportionalScaling(float length) {
        float scale = engineProperties.getFloatProperty("AxisSize") / (float) axisDirection.length();
        length *= scale;
        if (Float.isNaN(length)) {
            length = 1;
        }
        return length;
    }

    @Override
    protected char getIntersectedAxis(int x, int y) {
        ISceneCollisionManager cm = manager3D.getSceneManager().getSceneCollisionManager();
        vector2di basicPos = cm.getScreenCoordinatesFrom3DPosition(gizmo_position);
        float axisSizes = getGizmoLength(gizmo_position);
        vector2di posX = cm.getScreenCoordinatesFrom3DPosition(gizmo_position.addOperator(new vector3df(axisSizes, 0, 0)));
        vector2di posY = cm.getScreenCoordinatesFrom3DPosition(gizmo_position.addOperator(new vector3df(0, axisSizes, 0)));
        vector2di posZ = cm.getScreenCoordinatesFrom3DPosition(gizmo_position.addOperator(new vector3df(0, 0, axisSizes)));
        //Create crossed lines on mouse position. We will check intersection with this cross and axises

        char axisSelected;
        if (intersectionLineWithMouseCross(basicPos, posX)) {
            axisSelected = 'x';
        } else if (intersectionLineWithMouseCross(basicPos, posY)) {
            axisSelected = 'y';
        } else if (intersectionLineWithMouseCross(basicPos, posZ)) {
            axisSelected = 'z';
        } else {
            axisSelected = ' ';
        }

        return axisSelected;
    }
    private ISceneNode previousParent;

    @Override
    protected void onEndTransformation(ISceneNode node) {
        if (previousParent != null) {
            node.setDynamicParent(previousParent);
        }

        super.onEndTransformation(node);
    }

    @Override
    protected void getNodeStateBeforeChangeState(ISceneNode node) {
        previousParent = null;
        ISceneNode root = manager3D.getSceneManager().getRootSceneNode();
        if (!node.getParent().equals(root)) {
            previousParent = node.getParent();
            node.setDynamicParent(root);
        }

        node_state_before_changing = new vector3df(node.getPosition());
    }
}